package org.jeecg.modules.clue.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.stream.CollectorUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.api.vo.Result;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.FillRuleUtil;
import org.jeecg.modules.clue.entity.ClueRecord;
import org.jeecg.modules.clue.entity.ClueRecordTask;
import org.jeecg.modules.clue.entity.ClueTpCarConfig;
import org.jeecg.modules.clue.entity.ClueUserTpCarRelate;
import org.jeecg.modules.clue.enums.ClueInviteStatus;
import org.jeecg.modules.clue.enums.ClueWriteMode;
import org.jeecg.modules.clue.enums.TaskPushStatus;
import org.jeecg.modules.clue.job.ClueTaskPushListener;
import org.jeecg.modules.clue.mapper.ClueRecordMapper;
import org.jeecg.modules.clue.req.ClueHistoryResend;
import org.jeecg.modules.clue.service.IClueRecordService;
import org.jeecg.modules.clue.service.IClueRecordTaskService;
import org.jeecg.modules.clue.service.IClueTpCarConfigService;
import org.jeecg.modules.clue.service.IClueUserTpCarRelateService;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * @Description: 线索记录
 * @Author: jeecg-boot
 * @Date: 2025-01-08
 * @Version: V1.0
 */
@Service
@Slf4j
public class ClueRecordServiceImpl extends ServiceImpl<ClueRecordMapper, ClueRecord> implements IClueRecordService {


    @Resource
    IClueUserTpCarRelateService clueUserTpCarRelateService;
    @Resource
    ISysUserService sysUserService;
    @Resource
    IClueTpCarConfigService clueTpCarConfigService;
    @Resource
    IClueRecordTaskService clueRecordTaskService;

    @Resource
    StringRedisTemplate stringRedisTemplate;



    @Override
    public void distributeTask(ClueRecord clueRecord) {
        SysUser sysUser = sysUserService.getUserByName(clueRecord.getSource());
        // 查询当前线索来源，启用的三方平台
        List<ClueUserTpCarRelate> tpCarRelateList = clueUserTpCarRelateService
                .list(new LambdaQueryWrapper<ClueUserTpCarRelate>()
                        .eq(ClueUserTpCarRelate::getUserId, sysUser.getId())
                        .eq(ClueUserTpCarRelate::getStatus, "Y")

                );

        List<ClueUserTpCarRelate> pushCarPlateList = tpCarRelateList.parallelStream().filter(new Predicate<ClueUserTpCarRelate>() {
            @Override
            public boolean test(ClueUserTpCarRelate clueUserTpCarRelate) {
                String cityListStr = Optional.ofNullable(clueUserTpCarRelate.getCityList()).orElseGet(() -> "");
                return StringUtils.isBlank(clueUserTpCarRelate.getCityList()) || Arrays.asList(cityListStr.split(",")).contains(clueRecord.getCity());
            }
        }).collect(Collectors.toList());

        if (pushCarPlateList.isEmpty()) {
            return;
        }
        // 三方平台Map，方便查询数据
        Map<String, ClueTpCarConfig> carPlateMap = clueTpCarConfigService.list(new LambdaQueryWrapper<ClueTpCarConfig>().in(ClueTpCarConfig::getId, pushCarPlateList.parallelStream().map(ClueUserTpCarRelate::getTpCarId).collect(Collectors.toList())))
                .parallelStream().collect(Collectors.toMap(ClueTpCarConfig::getId, v -> v));

        List<ClueRecordTask> taskList = pushCarPlateList.stream().map(new Function<ClueUserTpCarRelate, ClueRecordTask>() {
            @Override
            public ClueRecordTask apply(ClueUserTpCarRelate clueUserTpCarRelate) {
                ClueRecordTask clueRecordTask = new ClueRecordTask();
                BeanUtil.copyProperties(clueRecord, clueRecordTask, "id");
                clueRecordTask.setRecordId(clueRecord.getId());
                clueRecordTask.setTaskNo(Objects.requireNonNull(FillRuleUtil.executeRule("clue_task_no_rule", (JSONObject) JSON.toJSON(clueRecordTask))).toString());
                clueRecordTask.setDelayPushTime(clueUserTpCarRelate.getDelayPushTime());

                clueRecordTask.setTpCarConfigCode(carPlateMap.get(clueUserTpCarRelate.getTpCarId()).getCode());
                clueRecordTask.setTpUsername(clueUserTpCarRelate.getTpUsername());
                clueRecordTask.setTpPassword(clueUserTpCarRelate.getTpPassword());
                clueRecordTask.setTpSecretKey(clueUserTpCarRelate.getTpSecretKey());
                clueRecordTask.setPushStatus(TaskPushStatus.待推送.status);
                 return clueRecordTask;
            }
        }).collect(Collectors.toList());

        // 保存Task
        clueRecordTaskService.saveBatch(taskList);
        log.info("待推送 taskList {}", JSON.toJSON(taskList));
        for (ClueRecordTask recordTask : taskList) {
            ZSetOperations<String, String> opsForZSet = stringRedisTemplate.opsForZSet();
            opsForZSet.add(ClueTaskPushListener.Topic, recordTask.getId(), System.currentTimeMillis() + Optional.ofNullable(recordTask.getDelayPushTime()).orElse(0)*1000);
        }


    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveClueRecord(ClueRecord clueRecord) {
        String source = clueRecord.getSource();
        if (StringUtils.isBlank(source)) {
            throw new RuntimeException("线索来源不能为空");
        }
        if (StringUtils.isBlank(clueRecord.getCity())) {
            throw new RuntimeException("城市不能为空");
        }
        // 检测用户可用性
        SysUser sysUser = sysUserService.getUserByName(source);
        if (sysUser == null) {
            throw new RuntimeException("线索来源用户名不存在,请联系系统管理员");
        }
        Result result = sysUserService.checkUserIsEffective(sysUser);
        if (CommonConstant.SC_INTERNAL_SERVER_ERROR_500.equals(result.getCode())) {
            throw new RuntimeException(result.getMessage());
        }
        // 查询当前线索来源，启用的三方平台
        List<ClueUserTpCarRelate> tpCarRelateList = clueUserTpCarRelateService.list(new LambdaQueryWrapper<ClueUserTpCarRelate>()
                .eq(ClueUserTpCarRelate::getUserId, sysUser.getId())
                .eq(ClueUserTpCarRelate::getStatus, "Y"))
                ;

        List<ClueUserTpCarRelate> pushCarPlateList = tpCarRelateList.parallelStream().filter(new Predicate<ClueUserTpCarRelate>() {
            @Override
            public boolean test(ClueUserTpCarRelate clueUserTpCarRelate) {
                String cityListStr = Optional.ofNullable(clueUserTpCarRelate.getCityList()).orElseGet(() -> "");
                return StringUtils.isBlank(clueUserTpCarRelate.getCityList()) || Arrays.asList(cityListStr.split(",")).contains(clueRecord.getCity());
            }
        }).collect(Collectors.toList());

        if (pushCarPlateList.isEmpty()) {
           throw new RuntimeException("当前渠道不存在推送平台");
        }

        // 去重检查
        duplicateCheck(clueRecord.getPhone());


        // 保存当前记录
        save(clueRecord);
        // 分发任务
        this.distributeTask(clueRecord);
    }

    private void duplicateCheck(String phone) {
        Date currentDate = new Date();
        DateTime before30Date = DateUtil.offsetDay(currentDate, -30);
        List<ClueRecord> list = list(new LambdaQueryWrapper<ClueRecord>()

                .eq(ClueRecord::getPhone,phone)
                .between(ClueRecord::getCreateTime, before30Date, currentDate));
        if (CollectionUtil.isNotEmpty(list)) {
            throw new RuntimeException("手机号重复");
        }
    }

    @Override
    public List<ClueRecord> historySearch(String source, String startCreateTime, String endCreateTime) {
        List<ClueRecord> recordList = list(new LambdaQueryWrapper<ClueRecord>().eq(ClueRecord::getSource, source)
                .between(ClueRecord::getCreateTime, startCreateTime, endCreateTime)

        );

        return recordList;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void historyResend(ClueHistoryResend clueHistoryResend) {
        String source = clueHistoryResend.getSource();
        if (StringUtils.isEmpty(source)) {
            throw new RuntimeException("用户不能为空");
        }
        SysUser sysUser = sysUserService.getUserByName(source);
        if (null == sysUser) {
            throw new RuntimeException("用户不存在");
        }

        String tagAreaConfigId = clueHistoryResend.getTagAreaConfigId();
        if (StringUtils.isEmpty(source)) {
            throw new RuntimeException("平台不能为空");
        }
        List<ClueUserTpCarRelate> tpCarRelateList = clueUserTpCarRelateService.list(new LambdaQueryWrapper<ClueUserTpCarRelate>()
                .eq(ClueUserTpCarRelate::getUserId, sysUser.getId())
                .eq(ClueUserTpCarRelate::getTpCarId, tagAreaConfigId)
        );
        if (tpCarRelateList.isEmpty()) {
            throw new RuntimeException("用户不存在该平台");
        }
        for (ClueUserTpCarRelate carRelate : tpCarRelateList) {
            if (!"Y".equals(carRelate.getStatus())) {
                throw new RuntimeException("该平台已被禁用");
            }
        }

        if (clueHistoryResend.getCludRecordIdList().isEmpty()) {
            return;
        }
        List<ClueRecord> records = list(new LambdaQueryWrapper<ClueRecord>().in(ClueRecord::getId, clueHistoryResend.getCludRecordIdList()));
        if (records.isEmpty()) {
            return;
        }
        List<ClueRecord> clueRecords = records.parallelStream().map(clueRecord -> {
            ClueRecord cr = new ClueRecord();

            cr.setRecordNo(Objects.requireNonNull(FillRuleUtil.executeRule("clue_record_no_rule", (JSONObject) JSON.toJSON(clueRecord))).toString());
            cr.setWriteMode(ClueWriteMode.历史转发.status);
            cr.setPhone(clueRecord.getPhone());
            cr.setCity(clueRecord.getCity());
            cr.setSource(clueRecord.getSource());

            return cr;
        }).collect(Collectors.toList());

        for (ClueRecord clueRecord : clueRecords) {
            // 去重检查
            duplicateCheck(clueRecord.getPhone());
            saveClueRecord(clueRecord);

        }




    }

    @Override
    public Result<String> h5Add(ClueRecord clueRecord) {
        String source = clueRecord.getSource();
        if (StringUtils.isBlank(source)) {
            return Result.error("线索来源不能为空");
        }
        if (StringUtils.isBlank(clueRecord.getCity())) {
            return Result.error("城市不能为空");
        }
        // 检测用户可用性
        SysUser sysUser = sysUserService.getUserByName(source);
        if (sysUser == null) {
            return Result.error("线索来源用户名不存在,请联系系统管理员");
        }
        Result result = sysUserService.checkUserIsEffective(sysUser);
        if (CommonConstant.SC_INTERNAL_SERVER_ERROR_500.equals(result.getCode())) {
            return Result.error(result.getMessage());

        }
        // 查询当前线索来源，启用的三方平台
        List<ClueUserTpCarRelate> tpCarRelateList = clueUserTpCarRelateService
                .list(new LambdaQueryWrapper<ClueUserTpCarRelate>()
                        .eq(ClueUserTpCarRelate::getUserId, sysUser.getId())
                        .eq(ClueUserTpCarRelate::getStatus, "Y")

                );

        List<ClueUserTpCarRelate> pushCarPlateList = tpCarRelateList.parallelStream().filter(new Predicate<ClueUserTpCarRelate>() {
            @Override
            public boolean test(ClueUserTpCarRelate clueUserTpCarRelate) {
                String cityListStr = Optional.ofNullable(clueUserTpCarRelate.getCityList()).orElseGet(() -> "");
                return StringUtils.isBlank(clueUserTpCarRelate.getCityList()) || Arrays.asList(cityListStr.split(",")).contains(clueRecord.getCity());
            }
        }).collect(Collectors.toList());

        if (pushCarPlateList.isEmpty()) {
            return Result.error("平台不覆盖");
        }
        // 去重检查
        duplicateCheck(clueRecord.getPhone());


        clueRecord.setRecordNo(Objects.requireNonNull(FillRuleUtil.executeRule("clue_record_no_rule", (JSONObject) JSON.toJSON(clueRecord))).toString());
        clueRecord.setWriteMode(ClueWriteMode.网络推广.status);

        // 保存当前记录
        save(clueRecord);
        // 分发任务
        this.distributeTask(clueRecord);
        return Result.OK("录入成功");
    }

    @Override
    public String stat() {
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        String roleCode = sysUser.getRoleCode();
        List<String> roleCodes = Arrays.asList(Optional.ofNullable(roleCode).orElse("").split(","));
        long yesterdayWriteNum = 0;
        long todayWriteNum = 0;

        // 当前角色不是 管理员,
        if (!roleCodes.contains("plain_admin") &&  !roleCodes.contains("admin")) {
            yesterdayWriteNum = count(new LambdaQueryWrapper<ClueRecord>()
                    .eq(ClueRecord::getSource,sysUser.getUsername())
                    .and(new Consumer<LambdaQueryWrapper<ClueRecord>>() {
                        @Override
                        public void accept(LambdaQueryWrapper<ClueRecord> clueRecordLambdaQueryWrapper) {
                            clueRecordLambdaQueryWrapper.last(" DATE(create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY)");
                        }
                    }));
            todayWriteNum = count(new LambdaQueryWrapper<ClueRecord>()
                    .eq(ClueRecord::getSource,sysUser.getUsername())
                    .and(new Consumer<LambdaQueryWrapper<ClueRecord>>() {
                        @Override
                        public void accept(LambdaQueryWrapper<ClueRecord> clueRecordLambdaQueryWrapper) {
                            clueRecordLambdaQueryWrapper.last(" DATE(create_time) = CURDATE()");
                        }
                    }));
        }else {// 统计所有
            yesterdayWriteNum = count(new LambdaQueryWrapper<ClueRecord>().last("where DATE(create_time) = DATE_SUB(CURDATE(), INTERVAL 1 DAY) "));
            todayWriteNum = count(new LambdaQueryWrapper<ClueRecord>().last("where DATE(create_time) = CURDATE()"));
        }


        return String.format("昨日录入 %s ,今日录入 %s",yesterdayWriteNum,todayWriteNum);
    }
}
